/* ==============================================================================
Project Name	: 6-Axis controller for robotic arm with 3 phase motor

Model Number	: FD0B098

File Name		: fpga.c

Description		: Handles communication with Microsemi ProASIC3 A3P1000 FPGA
				  through parallel interface.

=================================================================================
 History:

 Date			Version			Remarks
---------------------------------------------------------------------------------

============================================================================== */

/*** INCLUDES ******************************************************************/
#include "Settings.h"
#include "Fpga.h"


/*** GLOBAL VARIABLES **********************************************************/
#pragma DATA_SECTION(FPGARegs,"FPGARegsFile");
volatile Uint32 FPGARegs[128];

//#pragma DATA_SECTION(FpgaRegs, "Emif1_CS2_Data");
//volatile struct FPGA_REG FpgaRegs;


/*** FUNCTIONS *****************************************************************/
/*
 * Function name: 	FPGA_SoftReset_InitPin
 * Description	: 	Configure the pin used for software reset the FPGA.
 * Input		: 	None
 * Output		: 	None
 */
void FPGA_SoftReset_InitPin(void)
{
    #ifndef MATLAB_MEX_FILE

	GPIO_SetupPinOptions(1, GPIO_OUTPUT, GPIO_PULLUP);
    
    #endif
}


/*
 * Function name: 	FPGA_SoftReset
 * Description	: 	Enable/Disable the FPGA software reset.
 * Input		: 	- State			Enable or disable the software reset
 * Output		: 	None
 */
//void FPGA_SoftReset(Uint16 Status)
//{
//	if (Status == 1)
//		GpioDataRegs.GPACLEAR.bit.GPIO1 = 1;
//	else
//		GpioDataRegs.GPASET.bit.GPIO1 = 1;
//
//	DELAY_US(10);
//}


/*
 * Function name: 	Init_Emif1
 * Description	: 	Initialize EMIF1 which is used to communicate with FPGA.
 * Input		: 	None
 * Output		: 	None
 */
void Init_Emif1 (void)
{
	Uint16 i =0;

    #ifndef MATLAB_MEX_FILE

	EALLOW;
    CpuSysRegs.PCLKCR1.bit.EMIF1 = 1;
	ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x1;				// Configure to run EMIF1 on full Rate (EMIF1CLK = PLLSYSCLK / 2)
	Emif1ConfigRegs.EMIF1MSEL.all 			= 0x93A5CE71;		// CPU1 is the master
	Emif1ConfigRegs.EMIF1ACCPROT0.all 		= 0x0;				// Disable write protections
	Emif1ConfigRegs.EMIF1COMMIT.all 		= 0x1;				// Commit the protection configuration
	Emif1ConfigRegs.EMIF1LOCK.all 			= 0x1;				// Lock the configuration
	EDIS;

	// Setup pin muxing
	GPIO_SetupPinMux(31, 0, 2);					// nWE
	GPIO_SetupPinMux(34, 0, 2);					// nCS0
	GPIO_SetupPinMux(36, 0, 2);					// WAIT
	GPIO_SetupPinMux(37, 0, 2);					// nOE
	GPIO_SetupPinMux(38, 0, 2);					// A0
	GPIO_SetupPinMux(39, 0, 2);					// A1
	GPIO_SetupPinMux(40, 0, 2);					// A2
	GPIO_SetupPinMux(41, 0, 2);					// A3
	GPIO_SetupPinMux(44, 0, 2);					// A4
	GPIO_SetupPinMux(45, 0, 2);					// A5
	GPIO_SetupPinMux(46, 0, 2);					// A6
	GPIO_SetupPinMux(47, 0, 2);					// A7
//	GPIO_SetupPinMux(48, 0, 2);					// A8
//	GPIO_SetupPinMux(49, 0, 2);					// A9
//	GPIO_SetupPinMux(50, 0, 2);					// A10
//	GPIO_SetupPinMux(51, 0, 2);					// A11
//	GPIO_SetupPinMux(52, 0, 2);					// A12
//	GPIO_SetupPinMux(86, 0, 2);					// A13
//	GPIO_SetupPinMux(87, 0, 2);					// A14
//	GPIO_SetupPinMux(88, 0, 2);					// A15

    for (i=53; i<=85; i++)
    {
        if (i != 84)
        {
        	GPIO_SetupPinMux(i, 0, 2);			// D0-D31
            GPIO_SetupPinOptions(i, 0, 0x31);
        }
    }

    EALLOW;
    //Configure the access timing for CS2 space
	Emif1Regs.ASYNC_CS2_CR.all = (EMIF_ASYNC_ASIZE_32	|			// 32 bit data bus
								  EMIF_ASYNC_TA_4		|			// 4 turn around cycles
								  EMIF_ASYNC_RHOLD_8	|			// 8 EM1CLK cycles for read hold time
								  EMIF_ASYNC_RSTROBE_32	|			// 64 EM1CLK cycles for read strobe time
								  EMIF_ASYNC_RSETUP_8	|			// 16 EM1CLK cycles for read setup time
								  EMIF_ASYNC_WHOLD_8	|			// 8 EM1CLK cycles for write hold time
								  EMIF_ASYNC_WSTROBE_32	|			// 64 EM1CLK cycles for write strobe time
								  EMIF_ASYNC_WSETUP_8	|			// 16 EM1CLK cycles for write setup time
								  EMIF_ASYNC_EW_DISABLE	|			// Disable extended wait mode
								  EMIF_ASYNC_SS_DISABLE				// Disable strobe select mode
								 );	
	EDIS;
    
    #endif
}


void FPGA_SetupEnablePin_func(void)
{
    #ifndef MATLAB_MEX_FILE
    GPIO_SetupPinOptions(1, GPIO_OUTPUT, (GPIO_PULLUP | GPIO_ASYNC));
    #endif
}
void FPGA_Enable_func(void)
{
    #ifndef MATLAB_MEX_FILE

    GpioDataRegs.GPASET.bit.GPIO1 = 1;
    #endif
}
void FPGA_Disable_func(void)	
{
    #ifndef MATLAB_MEX_FILE

    GpioDataRegs.GPACLEAR.bit.GPIO1 = 1;
    #endif
}
